﻿/*
 * @author: wizardc
 */

using System.IO;
using Dou.Job;

namespace Demo.WorldMap.GPU
{
    /// <summary>
    /// 包含了一颗树中所有 GPU 绘制相关信息的容器类
    /// </summary>
    public class GPUDrawContainer
    {
        private GPUResInfo[] _resInfos;
        private Stream _dataStream;

        private GPUBatchDraw[] _batchDraws;
        
        public int resCount => _resInfos.Length;
        
        public int batchCount => _batchDraws.Length;
        
        /// <summary>
        /// 初始化容器
        /// </summary>
        public void Init(GPUStaticRenderRes[] res, GPUStaticRenderLODRes[] lodRes, Stream dataStream)
        {
            _dataStream = dataStream;
            
            _resInfos = new GPUResInfo[res.Length];
            for (var i = 0; i < res.Length; i++)
            {
                var resInfo = new GPUResInfo();
                resInfo.Init(res[i], _dataStream);
                _resInfos[i] = resInfo;
            }

            _batchDraws = new GPUBatchDraw[lodRes.Length];
            for (var i = 0; i < lodRes.Length; i++)
            {
                var batchDraw = new GPUBatchDraw();
                batchDraw.Init(lodRes[i]);
                _batchDraws[i] = batchDraw;
            }
        }

        /// <summary>
        /// 设置当前容器的 LOD 等级
        /// </summary>
        public void SetLOD(int lod)
        {
            for (int i = 0; i < _resInfos.Length; i++)
            {
                _resInfos[i].SetLOD(lod);
            }
        }

        /// <summary>
        /// 获取单个资源信息对象
        /// </summary>
        [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
        [Il2CppSetOption(Option.NullChecks, false)]
        public GPUResInfo GetResInfo(int resId)
        {
            return _resInfos[resId];
        }

        /// <summary>
        /// 获取批次绘制对象
        /// </summary>
        [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
        [Il2CppSetOption(Option.NullChecks, false)]
        public GPUBatchDraw GetBatchDraw(int batchDrawId)
        {
            return _batchDraws[batchDrawId];
        }
        
        /// <summary>
        /// 从数据流中拷贝对应的数据
        /// </summary>
        [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
        [Il2CppSetOption(Option.NullChecks, false)]
        public void CopyData()
        {
            for (var i = 0; i < _resInfos.Length; i++)
            {
                var resInfo = _resInfos[i];
                resInfo.CopyData();
            }
        }

        /// <summary>
        /// 清除所有绘制批次中的数据
        /// </summary>
        [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
        [Il2CppSetOption(Option.NullChecks, false)]
        public void ClearBatchData()
        {
            for (var i = 0; i < _batchDraws.Length; i++)
            {
                var batchDraw = _batchDraws[i];
                batchDraw.ClearTransform();
            }
        }

        /// <summary>
        /// 尝试加载资源
        /// </summary>
        [Il2CppSetOption(Option.ArrayBoundsChecks, false)]
        [Il2CppSetOption(Option.NullChecks, false)]
        public void TryLoadRes()
        {
            for (var i = 0; i < _batchDraws.Length; i++)
            {
                var batchDraw = _batchDraws[i];
                batchDraw.TryLoadRes();
            }
        }
        
        /// <summary>
        /// 销毁
        /// </summary>
        public void Dispose()
        {
            for (var i = 0; i < _resInfos.Length; i++)
            {
                var resInfo = _resInfos[i];
                resInfo.Dispose();
            }
            _resInfos = null;

            for (var i = 0; i < _batchDraws.Length; i++)
            {
                var batchDraw = _batchDraws[i];
                batchDraw.Dispose();
            }
            _batchDraws = null;
        }
    }
}
